<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>原型对象</title>
</head>
<body>
<script>
    /*原型prototype 我们所创建的每一个函数，解析器都会向函数添加一个属性prototype
    *   这个属性对应一个对象，这个对象就是我们所谓的原型对象
    *   如果函数作为普通函数调用prototype没有任何作用，
    *   当函数以构造函数调用时，它所创建的对象都会又一个隐含的属性，指向该构造函数的原型对象
    *   我们可以通过__proto__两个下划线来访问属性
    *   原型对象就相当于一个公共区域，所有同一类的实例都可以访问这个原型对象
    *   我们可以将对象中共有的内容，统一设置到原型对象中，
    *   当我们访问对象的一个属性和方法时 它会先在自身中寻找，如果有则直接使用，如果没有则会去原型对象中寻找， 如果找到直接使用
    *   以后我们创建构造函数时，可以将这些对象共有的属性和方法，统一添加到构造函数的原型对象中，
    *   这样就不用对每一个对象添加，也不会影响全局作用域，就可以使每个对象都具有这些属性和方法了
    *   使用in 检查对象中是否有某个属性时，如果对象中没有 原型对象中有 则返回true
    * 可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性
    * 原型对象也是对象，所以也有原型
    *       当我们在使用一个对象的属性和方法时，会先在自身中寻找， 自身中如果有 就直接使用
    *       如果没有则去原型对象中寻找，如果原型对象中有 则使用，如果没有则去原型的原型去寻找
    *       直到找到Object对象的原型，Object对象的原型没有原型，如果undefined依然没有找到，则返回undefined
    *   当我们直接在页面中打印一个对象时，事件上是输出对象tostring（）方法返回值
    *   如果我们需要输出的对象不输出（object object）可以为对象添加一个toString()方法
    *
    *
    * */
    //举例1
    function MyClass() {

    }
    var mc=new MyClass();
    console.log(MyClass.prototype);
    console.log(mc.__proto__==MyClass.prototype);// mc.__proto__即mc的原型对象，说明二者是指向同一个对象
    //举例2

    function Person() {

    }
    Person.prototype.name="孙悟空";//向原型对象中添加属性值，实例per从类Person中获得了name,所以per.name就是原型对象的名字
    var per=new Person();
        per.age=18;
    console.log(per.name);//返回值是孙悟空
    //使用in 检查对象中是否有某个属性时，如果对象中没有 原型对象中有 则返回true
    console.log("name" in per);//name是否在per实例中  返回值是true 说明在 返回值是false 说明不在
    //可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性
    console.log(per.hasOwnProperty("name"));//返回false
    console.log(per.hasOwnProperty("age"));//返回true
    console.log(per.__proto__);//返回object
    console.log(per.__proto__.__proto__);//返回object
    console.log(per.__proto__.__proto__.__proto__);//返回null
</script>
</body>
</html>